package com.ws.base.common.support;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import jxl.Cell;
import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import com.ws.base.common.WSAppLogger;
import com.ws.base.common.entity.EntitySupport;

public abstract class ExcelSupport<T extends EntitySupport> {

    private final WSAppLogger logger = WSAppLogger
            .getWSAppLogger(ExcelSupport.class);

    private String filePath;

    private String sheetName;

    private String[] property;

    private List<String[]> records;

    private int sheetNum = 0;

    protected void createXls() {
        try {
            WritableWorkbook workbook = Workbook.createWorkbook(new File(
                    getFilePath()));
            WritableSheet sheet = workbook.createSheet(getSheetName(),
                    getSheetNum());
            sheet.setName(getSheetName());
            loadXlsTemplate(sheet);
            workbook.write();
            close(workbook);

        } catch (IOException e) {
            logger.error(e, "create xls file error");
        }
    }

    protected void loadXlsTemplate(WritableSheet sheet) {
        writeLine(sheet, getProperty(), 0);

        for (int i = 0; i < getRecords().size(); i++) {
            writeLine(sheet, getRecords().get(i), i + 1);
        }
    }

    protected List<T> readXls(String sheetName) {
        List<T> list = new ArrayList<T>();

        try {
            Workbook workbook = Workbook.getWorkbook(new File(getFilePath()));
            Sheet sheet = workbook.getSheet(sheetName);
            list.addAll(read(sheet, sheetName));
            workbook.close();
        } catch (BiffException e) {
            logger.error(e, "open xls file error");
        } catch (IOException e) {
            logger.error(e, "open xls file error");
        }

        return list;
    }

    protected void updateXls(List<T> t) {
        Workbook wb = null;
        WritableWorkbook book = null;

        try {
            wb = Workbook.getWorkbook(new File(getFilePath()));
            book = Workbook.createWorkbook(new File(getFilePath()), wb);

            update(book, t);

        } catch (Exception e) {
            logger.error(e, "update xls file error");
        } finally {
            try {
                book.write();
                book.close();
            } catch (IOException e) {
                logger.error(e, "update xls file error");
            }
            wb.close();
        }
    }

    protected abstract void update(WritableWorkbook book, List<T> t);

    protected List<T> read(Sheet sheet, String sheetName) {
        List<T> list = new ArrayList<T>();
        int rows = sheet.getRows();

        for (int i = 0; i < rows; i++) {
            T t = readLine(sheet, i, sheetName);
            if (null != t) {
                list.add(t);
            }
        }

        return list;
    }

    protected T readLine(Sheet sheet, int lineNum, String sheetName) {
        return null;
    }

    private void writeLine(WritableSheet sheet, String[] record, int lineNum) {
        try {
            for (int i = 0; i < record.length; i++) {
                Label label = new Label(i, lineNum, record[i]);
                sheet.addCell(label);
            }
        } catch (RowsExceededException e) {
            logger.error(e, "writeLine xls file error");
        } catch (WriteException e) {
            logger.error(e, "writeLine xls file error");
        }
    }

    public String getCellVal(Cell[] cells, int index) {
        String str = null;

        if (cells.length > index) {
            if (CellType.EMPTY == cells[index].getType()) {

            } else if (CellType.LABEL == cells[index].getType()) {
                str = cells[index].getContents();
            } else if (CellType.NUMBER == cells[index].getType()) {
                str = cells[index].getContents();
            } else if (CellType.DATE == cells[index].getType()) {
                str = cells[index].getContents();
            }
        }

        return str;
    }

    public void close(WritableWorkbook workbook) {
        try {
            if (null != workbook) {
                workbook.close();
            }
        } catch (IOException e) {
            logger.error(e, "close xls file error");
        }
    }

    public int getSheetNum() {
        return sheetNum;
    }

    public void setSheetNum(int sheetNum) {
        this.sheetNum = sheetNum;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public String[] getProperty() {
        return property;
    }

    public void setProperty(String[] property) {
        this.property = property;
    }

    public List<String[]> getRecords() {
        return records;
    }

    public void setRecords(List<String[]> records) {
        this.records = records;
    }

}
